package com.mspbots.ticketai.graderule;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mspbots.ticketai.GradeRuleInterceptorAdapter;
import com.mspbots.ticketai.model.Ticket;
import com.mspbots.ticketai.model.TicketRule;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


@Log4j2
@Service(value = "TICKET_OWNER_POINT_RULE")
public class TicketOwnerRuleInterceptor extends GradeRuleInterceptorAdapter {

    private List<TicketOwnerParam> params;

    @Override
    public void prepare(TicketRule rule) {
        params = this.objectMapper.convertValue(rule.getParams(), new TypeReference<>() {
        });
    }

    @Override
    public void process(Ticket ticket) {
        AtomicInteger order = new AtomicInteger();
        if (!StringUtils.isEmpty(ticket.getOwner()) && !StringUtils.isEmpty(ticket.getIdentifierCwId())
                && ticket.getOwner().equals(ticket.getIdentifierCwId())) {
            params.parallelStream().filter(item -> item.isSelected()).forEach(item -> order.addAndGet(item.getPoints()));
        }
        ObjectNode orderDetailNode = ticket.getOrderDetail() == null ? this.objectMapper.createObjectNode() : ticket.getOrderDetail().deepCopy();
        ObjectNode itemsNode = this.objectMapper.createObjectNode();
        itemsNode.put("ticketOwner", ticket.getOwner());
        itemsNode.put("identifier", ObjectUtils.isEmpty(ticket.getExtend().get("owner")) ? null : ticket.getExtend().get("owner").get("identifier").asText());
        itemsNode.put("point", order.get());
        orderDetailNode.set("ticketOwner", itemsNode);
        ticket.setOrderDetail(orderDetailNode);
        ticket.setOrder(ticket.getOrder() + order.get());
    }

    @Data
    static class TicketOwnerParam {
        private Integer index;
        private Integer points;
        private String condition;
        private boolean selected;
    }

}
